/**
 * 
 */
package ru.olympus.antonyhands.ao.server.item;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import ru.olympus.antonyhands.ao.server.db.AOData;
import ru.olympus.antonyhands.ao.shared.item.CraftInfoDTO;
import ru.olympus.antonyhands.ao.shared.item.ItemDTO;
import ru.olympus.antonyhands.ao.shared.item.ItemMarketPriceDTO;
import ru.olympus.antonyhands.ao.shared.util.LongUtilities;
import ru.olympus.antonyhands.ao.shared.util.StringPair;
import ru.olympus.antonyhands.ao.shared.util.StringUtilities;

/**
 * @author AntonyHands
 * @since 14.02.2012
 */
public class Item extends ItemBase
{

    public static final String TAG_NAME = "item";

    private static final String ATTRIBUTE_CATEGORY = "category";
    private static final String ATTRIBUTE_FIXED_PRICE = "fixed-price";
    private static final String ATTRIBUTE_MARKET_PRICE = "market-price";

    /**
     * Категория товара
     */
    private ItemCategory category;

    /**
     * Фиксированная цена (если есть)
     */
    private Long fixedPrice;

    /**
     * Рыночная цена
     */
    private Long marketPrice;

    /**
     * Крафтовый скилл, позволяющий делать данный предмет (если можно)
     */
    private CraftInfo craftInfo;

    /**
     * Предметы, которые можно скрафтить из данного
     */
    private List<CraftInfo> craftableItems = new ArrayList<CraftInfo>();

    // ==========================================================

    public Item()
    {
        // for the sake of persistence
    }

    public Item(String code, String title, ItemCategory category)
    {
        super(code, title);
        this.category = category;
    }

    @Override
    public String getTagName()
    {
        return TAG_NAME;
    }

    public Long getFixedPrice()
    {
        return fixedPrice;
    }

    public void setFixedPrice(Long fixedPrice)
    {
        this.fixedPrice = fixedPrice;
    }

    @Override
    public List<StringPair> getAttributes()
    {
        List<StringPair> attributes = super.getAttributes();
        attributes.add(new StringPair(ATTRIBUTE_CATEGORY, category.getCode()));
        attributes.add(new StringPair(ATTRIBUTE_FIXED_PRICE, StringUtilities.longToString(fixedPrice)));
        attributes.add(new StringPair(ATTRIBUTE_MARKET_PRICE, StringUtilities.longToString(marketPrice)));
        return attributes;
    }

    @Override
    public void setAttributes(List<StringPair> attributes)
    {
        super.setAttributes(attributes);
        for (StringPair pair : attributes) {
            if (ATTRIBUTE_CATEGORY.equals(pair.getKey()))
                category = AOData.getInstance().getItemCategoryByCode(pair.getValue());
            else if (ATTRIBUTE_FIXED_PRICE.equals(pair.getKey()))
                fixedPrice = StringUtilities.stringToLong(pair.getValue());
            else if (ATTRIBUTE_MARKET_PRICE.equals(pair.getKey()))
                marketPrice = StringUtilities.stringToLong(pair.getValue());
        }
    }

    public ItemCategory getItemCategory()
    {
        return category;
    }

    public void setCraftInfo(CraftInfo craftInfo)
    {
        this.craftInfo = craftInfo;
    }

    public CraftInfo getCraftInfo() {
		return craftInfo;
	}

	public void setMarketPrice(Long marketPrice) {
		this.marketPrice = marketPrice;
	}

	public Long getMarketPrice() {
		return marketPrice;
	}

	public void addCraftableItem(CraftInfo craftableItemInfo)
    {
        craftableItems.add(craftableItemInfo);
    }

	public Long getBestPrice()
	{
		return LongUtilities.getMin(fixedPrice, marketPrice, getCraftPrice());
	}

	public Long getCraftPrice()
	{
		if (craftInfo == null)
			return null;
		Long res = new Long(0);
		for (ItemQuantityPair iq : craftInfo.listInputItemsData())
			res += iq.getValue() * iq.getKey().getBestPrice();
		return res / craftInfo.getResultItemData().getValue();
	}

    public ItemDTO toDTO()
    {
    	CraftInfoDTO ciDTO = (craftInfo != null) ? craftInfo.getDTO() : null;
    	List<CraftInfoDTO> cis = new ArrayList<CraftInfoDTO>();
    	for (CraftInfo ci : craftableItems)
    	{
    		cis.add(ci.getDTO());
    	}
        ItemDTO dto = new ItemDTO(new StringPair(getCode(), getTitle()),
                new StringPair(category.getCode(), category.getTitle()),
                StringUtilities.longToString(fixedPrice), 
                StringUtilities.longToString(getCraftPrice()),
                StringUtilities.longToString(marketPrice), ciDTO, cis);
        return dto;
    }

    public Map<String, ItemMarketPriceDTO> getMarketPriceDTOForHierarchy()
    {
    	Map<String, ItemMarketPriceDTO> res = new HashMap<String, ItemMarketPriceDTO>();
    	// собственно предмет
    	res.put(getCode(), new ItemMarketPriceDTO(new StringPair(getCode(), getTitle()), StringUtilities.longToString(marketPrice)));
    	// составляющие его при крафте
    	if (craftInfo != null)
    		for (Item i : craftInfo.listSourceItems())
    			res.putAll(i.getMarketPriceDTOForHierarchy());
    	// то, что можно на предмет обменять
    	return res;
    }
}
